package com.hqd.ch03.v24.tx.transaction.interceptor;

import com.hqd.ch03.v24.aopalliance.intercept.MethodInterceptor;
import com.hqd.ch03.v24.aopalliance.intercept.MethodInvocation;
import com.hqd.ch03.v24.tx.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;
import java.sql.Connection;

public class TransactionInterceptor implements MethodInterceptor {
    private DataSource dataSource;

    public TransactionInterceptor() {

    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object resource = TransactionSynchronizationManager.getResource(dataSource);
        if (resource == null) {
            resource = dataSource.getConnection();
            TransactionSynchronizationManager.bindResource(dataSource, resource);
        }
        Connection connection = (Connection) resource;
        connection.setAutoCommit(false);
        try {
            Object retVal = invocation.proceed();
            connection.commit();
            return retVal;
        } catch (RuntimeException e) {
            connection.rollback();
            throw e;
        } finally {
            connection.close();
            TransactionSynchronizationManager.unbindResource(dataSource);
        }
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
}
